package com.fyp.client.ptma;

import java.io.IOException;

import org.apache.http.HttpResponse;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.text.Html;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.fyp.client.ptma.model.Downloader;
import com.fyp.client.ptma.model.User;
import com.fyp.client.ptma.utils.Device;
import com.fyp.client.ptma.utils.Helper;
import com.fyp.client.ptma.utils.NetworkConnectivity;
import com.fyp.client.ptma.xml.ResponseXml;
import com.fyp.client.ptma.xml.XmlBuilder;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.gcm.GoogleCloudMessaging;

public class SplashScreen extends AbstractActivity
{

	private ProgressBar progressBar;
	private TextView tvMessage;
	private View btnRegister;
	private Context context;
	static final String TAG = "GCM Demo";
	public static final String EXTRA_MESSAGE = "message";
	public static final String PROPERTY_REG_ID = "registration_id";
	private static final String PROPERTY_APP_VERSION = "appVersion";
	private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;

	private GoogleCloudMessaging gcm;

	/**
	 * Substitute you own sender ID here. This is the project number you got
	 * from the API Console, as described in "Getting Started."
	 */
	String SENDER_ID = "1084061521721";
	String regid;

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		progressBar.setIndeterminate(true);
		
		Device.createDirIfNotExists(Device.APP_FOLDER);
		context = getApplicationContext();
		if (NetworkConnectivity.isConntectedToInternet(context))
		{

			if (checkPlayServices())
			{
				gcm = GoogleCloudMessaging.getInstance(this);
				regid = getRegistrationId(context);

				if (regid.isEmpty())
				{
					registerInBackground();
				} else
				{
					sendRegistrationIdToBackend();
				}
			} else
			{
				sendRegistrationIdToBackend();
			}
		} else
		{
			progressBar.setVisibility(View.GONE);
			tvMessage.setText(getString(R.string.noInternet));
			tvMessage.setTextColor(Color.RED);
		}
	}

	@Override
	protected void onStart()
	{
		// TODO Auto-generated method stub
		super.onStart();

	}

	@Override
	protected void onResume()
	{

		super.onResume();

	}

	private class AuthenticationTask extends
			AsyncTask<Integer, Integer, Integer>
	{

		private static final int INTERNET_CHECK = 0;

		private static final int CHECK_AUTHENTICITY = 2;
		private static final int GETTING_APPLICATIONS = 3;

		@Override
		protected void onPreExecute()
		{
			// TODO Auto-generated method stub
			super.onPreExecute();
		}

		@Override
		protected void onPostExecute(Integer result)
		{

			super.onPostExecute(result);
			switch (result)
			{
			case ResponseXml.NOT_LOGGEDIN:
				switchScreen(Login.class, null);
				break;

			case ResponseXml.NOT_REGISTERED:
				progressBar.setVisibility(View.GONE);

				tvMessage.setTextColor(Color.RED);
				break;
			case ResponseXml.OK:
				switchScreen(ApplicationsList.class, 0);
				finish();
				break;
			}
		}

		@Override
		protected Integer doInBackground(Integer... arg0)
		{

			if (!NetworkConnectivity.isConntectedToInternet(SplashScreen.this))
			{
				publishProgress(INTERNET_CHECK);
				return 0;
			}

			// Authenticity Check
			publishProgress(CHECK_AUTHENTICITY);
			SharedPreferences pref = SplashScreen.this.getSharedPreferences(
					Constants.SHARED_PREFERENCE, Context.MODE_PRIVATE);

			String myEmail = Helper.decrypt(pref.getString(
					Constants.PREF_KEY_MYEMAIL, ""));

			String devEmail = Helper.decrypt(pref.getString(
					Constants.PREF_KEY_DEVEMAIL, ""));

			// Downloader
			Downloader downloader = new Downloader();
			downloader.setDeviceId(Device.getDeviceNumber(SplashScreen.this));
			downloader.setDeviceOs(Build.VERSION.RELEASE);
			downloader.setEmail(myEmail);
			User user = new User(devEmail);
			downloader.setUser(user);
			downloader.setGoogleRegId(regid);

			String authentic = pref
					.getString(Constants.PREF_KEY_AUTHENTIC, "1");

			if (myEmail != null && authentic != null
					&& Boolean.parseBoolean(authentic) && myEmail.length() > 0
					&& devEmail != null && devEmail.length() > 0)
			{
				return GETTING_APPLICATIONS;
			} else
			{

				String url = getString(R.string.WS_URL)
						+ getString(R.string.WS_AUHTENTICATE);
				HttpResponse response = NetworkConnectivity
						.performPostOperation(url,
								XmlBuilder.getXmlForAuthetication(downloader));
				try
				{
					ResponseXml wsResponse = Helper.getResponseObject(response);

					switch (wsResponse.getStatusCode())
					{
					case ResponseXml.NOT_LOGGEDIN:
						publishProgress(ResponseXml.NOT_LOGGEDIN);
						return ResponseXml.NOT_LOGGEDIN;
					case ResponseXml.NOT_REGISTERED:
						publishProgress(ResponseXml.NOT_REGISTERED);
						return ResponseXml.NOT_REGISTERED;

					case ResponseXml.OK:

						return ResponseXml.OK;
					default:
						break;
					}

				} catch (Exception e)
				{
					e.printStackTrace();
					publishProgress(ResponseXml.NOT_REGISTERED);
					return ResponseXml.NOT_REGISTERED;
				}

			}
			return 0;
		}

		@Override
		protected void onProgressUpdate(Integer... values)
		{

			super.onProgressUpdate(values);

			switch (values[0])
			{

			case INTERNET_CHECK:
				tvMessage.setText(getString(R.string.noInternet));
				tvMessage.setTextColor(Color.RED);
				progressBar.setVisibility(View.GONE);
				break;

			case CHECK_AUTHENTICITY:
				tvMessage.setText("Verifying your device...");
				break;

			case ResponseXml.NOT_REGISTERED:
				tvMessage.setText(getString(R.string.not_registered));
				btnRegister.setVisibility(View.VISIBLE);
				break;

			case 3:
				tvMessage.setText(getString(R.string.noInternet));
				break;
			default:
				break;
			}

		}
	}

	@Override
	int getContentView()
	{
		// TODO Auto-generated method stub
		return R.layout.splash_screen;
	}

	@Override
	void initViewRefereces()
	{
		progressBar = (ProgressBar) findViewById(R.id.progressBar);
		tvMessage = (TextView) findViewById(R.id.tvMessage);
		btnRegister = findViewById(R.id.btnRegister);
	}

	public void onClick(View v)
	{
		switch (v.getId())
		{
		case R.id.btnRegister:
			final Intent emailIntent = new Intent(
					android.content.Intent.ACTION_SEND);

			/* Fill it with Data */
			emailIntent.setType("plain/text");
			emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
					new String[]
					{ "" });
			emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,
					"Please white list");
			emailIntent
					.putExtra(
							android.content.Intent.EXTRA_TEXT,
							Html.fromHtml("Hi <p>Hi this is <name> , Please white list my device for testing <application name> </p>"));

			startActivity(Intent.createChooser(emailIntent, "Send email..."));
			break;

		default:
			break;
		}
	}

	/**
	 * @return Application's version code from the {@code PackageManager}.
	 */
	private static int getAppVersion(Context context)
	{
		try
		{
			PackageInfo packageInfo = context.getPackageManager()
					.getPackageInfo(context.getPackageName(), 0);
			return packageInfo.versionCode;
		} catch (NameNotFoundException e)
		{
			// should never happen
			throw new RuntimeException("Could not get package name: " + e);
		}
	}

	/**
	 * @return Application's {@code SharedPreferences}.
	 */
	private SharedPreferences getGcmPreferences(Context context)
	{
		// This sample app persists the registration ID in shared preferences,
		// but
		// how you store the regID in your app is up to you.
		return getSharedPreferences(SplashScreen.class.getSimpleName(),
				Context.MODE_PRIVATE);
	}

	/**
	 * Gets the current registration ID for application on GCM service.
	 * <p>
	 * If result is empty, the app needs to register.
	 * 
	 * @return registration ID, or empty string if there is no existing
	 *         registration ID.
	 */
	private String getRegistrationId(Context context)
	{
		final SharedPreferences prefs = getGcmPreferences(context);
		String registrationId = prefs.getString(PROPERTY_REG_ID, "");
		if (registrationId.isEmpty())
		{
			Log.i(TAG, "Registration not found.");
			return "";
		}
		// Check if app was updated; if so, it must clear the registration ID
		// since the existing regID is not guaranteed to work with the new
		// app version.
		int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION,
				Integer.MIN_VALUE);
		int currentVersion = getAppVersion(context);
		if (registeredVersion != currentVersion)
		{
			Log.i(TAG, "App version changed.");
			return "";
		}
		return registrationId;
	}

	private boolean checkPlayServices()
	{
		int resultCode = GooglePlayServicesUtil
				.isGooglePlayServicesAvailable(this);
		if (resultCode != ConnectionResult.SUCCESS)
		{
			if (GooglePlayServicesUtil.isUserRecoverableError(resultCode))
			{
				GooglePlayServicesUtil.getErrorDialog(resultCode, this,
						PLAY_SERVICES_RESOLUTION_REQUEST).show();
			} else
			{
				Log.i(TAG, "This device is not supported.");
				finish();
			}
			return false;
		}
		return true;
	}

	private void registerInBackground()
	{
		new AsyncTask<Integer, Integer, Integer>()
		{

			@Override
			protected Integer doInBackground(Integer... params)
			{

				try
				{
					if (gcm == null)
					{
						gcm = GoogleCloudMessaging.getInstance(context);
					}
					regid = gcm.register(SENDER_ID);
					storeRegistrationId(SplashScreen.this, regid);
					// You should send the registration ID to your server over
					// HTTP,
					// so it can use GCM/HTTP or CCS to send messages to your
					// app.
					// The request to your server should be authenticated if
					// your app
					// is using accounts.
					sendRegistrationIdToBackend();

					// For this demo: we don't need to send it because the
					// device
					// will send upstream messages to a server that echo back
					// the
					// message using the 'from' address in the message.

					// Persist the regID - no need to register again.

				} catch (IOException ex)
				{
					System.out.println(ex.getMessage());
					// If there is an error, don't just keep trying to register.
					// Require the user to click a button again, or perform
					// exponential back-off.
				}
				return 0;
			}

		}.execute();

	}

	private void sendRegistrationIdToBackend()
	{
		new AuthenticationTask().execute();
	}

	/**
	 * Stores the registration ID and app versionCode in the application's
	 * {@code SharedPreferences}.
	 * 
	 * @param context
	 *            application's context.
	 * @param regId
	 *            registration ID
	 */
	private void storeRegistrationId(Context context, String regId)
	{
		final SharedPreferences prefs = getGcmPreferences(context);
		int appVersion = getAppVersion(context);
		Log.i(TAG, "Saving regId on app version " + appVersion);
		SharedPreferences.Editor editor = prefs.edit();
		editor.putString(PROPERTY_REG_ID, regId);
		editor.putInt(PROPERTY_APP_VERSION, appVersion);
		editor.commit();
	}

}
